
var list = [];
function splitArrayIntoSubarrays(arr, chunkSize) {
	let subarrays = [];
	for (let i = 0; i < arr.length; i += chunkSize) {
		subarrays.push(arr.slice(i, i + chunkSize));
	}
	return subarrays;
}
function hexArrayToDecimal(hexArray) {
  // 将每个十六进制字符串转换为十进制数
  const bytes = hexArray.map(hex => parseInt(hex, 16));

  // 计算总和，假设最高位是第一个字节（大端字节序）
  return bytes.reduce((acc, byte, index) => {
    return (acc << 8) + byte;
  }, 0);
}
function calculateCRC(data) {
	let crc = 0xFFFF; // 初始值
	for (let pos = 0; pos < data.length; pos++) {
		crc ^= data[pos]; // 将数据与 CRC 当前值进行异或
		for (let i = 8; i !== 0; i--) { // 处理每一位
			if ((crc & 0x0001) !== 0) { // 如果最低位为 1
				crc >>= 1; // 向右移位
				crc ^= 0xA001; // 与多项式异或
			} else {
				crc >>= 1; // 否则仅移位
			}
		}
	}
	// 返回结果：低字节和高字节（交换顺序）
	return crc;
}
const UUID_SERVICE = "0000FFE1-0000-1000-8000-00805F9B34FB"; // 00001800-0000-1000-8000-00805F9B34FB
const UUID_WRITE = "0000FFE3-0000-1000-8000-00805F9B34FB";
import Vue from 'vue';
import Vuex from "vuex";
var lastCallTime = 0;
const throttle = (func, delay) => {
	return () => {
		const now = Date.now();
		if ((now - lastCallTime) >= delay) {
			func.apply(this, arguments);
			lastCallTime = now;
		}
	};
}
function debounce(func, wait) {
  let timeout;
  return function(...args) {
    // 清除前一次的定时器
    clearTimeout(timeout);

    // 设置新的定时器
    timeout = setTimeout(() => {
      func.apply(this, args); // 在定时器结束时执行函数
    }, wait);
  };
}

Vue.use(Vuex);
function calculateChecksum(bytes) {
  let sum = 0;
  for (let i = 0; i < bytes.length; i++) {
    sum += bytes[i];
  }
  return sum & 0xff; // 确保结果在0-255范围内
}
var dayData = [];
var monthData = [];
const store = new Vuex.Store({
	state: {
		currentDevice: uni.getStorageSync("currentDevice")?JSON.parse(uni.getStorageSync("currentDevice")):{
			deviceId: "",
			serviceId: "",
			characteristicId: ""
		},
		searchBluetList: [],
		list: [
			"", //0 运行状态 0: 运行异常 1: 电池过放 2: 风扇故障 3: 过温 4: DC输出短路 5: 内部温度故障  6: 外部温度故障
			"", //1 充电状态 0: 充电 1: 均充 2: 跟踪 3: 浮充 4: 充电限流 5: 充电降额 6: 远程禁止充电 7: 光伏板过压
			"", //2 控制状态 0: 充电输出开启  1: 负载输出开启 2: 风扇开启 3: 过充保护  4: 过压保护
			"", //3 光伏板电压 (Number(list[3])/10).toFixed(2)+'V'  
			"", //4 电池电压 (Number(list[4])/10).toFixed(2)+'V' 
			"", //5 充电电流 (Number(list[5])/10).toFixed(2)+'A' 
			"", //6 内部温度1 (Number(list[6])/10).toFixed(2)+'°C'
			"", //7 内部温度2 (Number(list[7])/10).toFixed(2)+'°C'
			"", //8 外部温度1 (Number(list[8])/10).toFixed(2)+'°C'
			"", //9 日发电量 举例Number(list[9]+list[10])/10000+'V'
			"", //10 日发电量 举例Number(list[9]+list[10])/10000+'V'
			"", //11 总发电量 举例Number(list[11]+list[12])/10000+'V'
			"", //12 总发电量 举例Number(list[11]+list[12])/10000+'V'
			"", //13 备用
			"", //14 备用
			"", //15 备用
			"", //16 备用
			"", //17 备用
			"", //18 备用
			"", //19 备用
			"", //20 备用
			"", //21 备用
			"", //22 备用
			"", //23 备用
			"", //24 备用
			"", //25 备用
			"", //26 备用
			"", //27 备用
			"", //29 备用
			"", //30 备用
			"", //31 备用
			"", //32 备用
			"", //33 0=铅酸免维护，1=铅酸胶体，2=铅酸液体，3=锂电
			"", //34 0=自动识别，1=12V，2=24V，3=36V，4=48V，5=60V，6=72V，7=84V，8=96V
			"", //35 电池数量 1~8只电池
			"", //36 均充电压上限 (Number(list[36])/10).toFixed(2)+'V' 
			"", //37 浮充电压上限 (Number(list[37])/10).toFixed(2)+'V' 
			"", //38 电池过压保护电压 (Number(list[38])/10).toFixed(2)+'V' 
			"", //39 电池过压恢复电压 (Number(list[39])/10).toFixed(2)+'V' 
			"", //40 电池过放保护电压 (Number(list[40])/10).toFixed(2)+'V' 
			"", //41 电池过放恢复电压 (Number(list[41])/10).toFixed(2)+'V'
			"", //42 硬件最大充电电流 (Number(list[42])/10).toFixed(2)+'A'
			"", //43 最大充电电流限制 (Number(list[43])/10).toFixed(2)+'A'
			"", //44 运行充电电流限制 (Number(list[44])/10).toFixed(2)+'A'
			"", //45 直流输出控制方式 0=关闭，1=自动（有电就输出），2=时控开/关，3=光控，4=远程控制
			"", //46 光控开启PV电压 (Number(list[46])/10).toFixed(2)+'V' 
			"", //47 光控关闭PV电压 (Number(list[47])/10).toFixed(2)+'V' 
			"", //48 延时开启时间 Number(list[48])+'S'
			"", //49 延时关闭时间 Number(list[49])+'S'
			"", //50 时控时间组标志 16bit数据，bit0:0=禁止，1=开启； bit1:0=禁止，1=开启
			"", //51 时控1开启时间 1开启时间
			"", //52 时控1关闭时间 1开启时间
			"", //53 时控1开启时间 1开启时间
			"", //54 时控1关闭时间 1开启时间
			"", //55 控制器型号编码
			"", //56 远程通信本机地址 
			"", //57 远程通信波特率 1~4: 1=1200，2=2400，3=4800，4=9600
			"", //58 系统时间 年+月 parseDateFromInt(list[28],'年','月')
			"", //59 系统时间 日+时 parseDayHourFromInt(list[59],'日','时')
			"", //60 系统时间 分+秒 parseDayHourFromInt(list[60],'分','秒')
			"", //61 故障记录01~10(共10条记录) 第1条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //62 故障记录01~10(共10条记录) 第2条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //63 故障记录01~10(共10条记录) 第3条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //64 故障记录01~10(共10条记录) 第4条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //65 故障记录01~10(共10条记录) 第5条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //66 故障记录01~10(共10条记录) 第6条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //67 故障记录01~10(共10条记录) 第7条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //68 故障记录01~10(共10条记录) 第8条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //69 故障记录01~10(共10条记录) 第9条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //70 故障记录01~10(共10条记录) 第10条 0=无故障/写0清故障 1= 运行异常 2=电池过放 2=风扇故障 3=过温 4=DC输出短路 5=内部温度故障 6=外部温度故障 7=光伏板过压 8=过充保护 9=过压保护 10=远程禁止充电
			"", //71 备用
			"", //72 备用
			"", //73 备用
			"", //74 备用
			"", //75 备用
			"", //76 备用
			"", //77 备用
			"", //78 备用
			"", //79 备用
			"", //80 备用
			"", //81 备用
			"", //82 备用
			"", //83 备用
			"", //84 备用
			"", //85 备用
			"", //86 备用
			"", //87 备用
			"", //88 备用
			"", //89 备用
			"", //90 备用
			"", //91 光伏板电压校准
			"", //92 电池电压校准
			"", //93 小电流校准
			"", //94 大电流校准
			"", //95 硬件电流限制设置
			"", //96 保存出厂设置
			"", //97 恢复出厂设置
		]
	},
	mutations: {
		setSearchBluetList(state, payload){
			state.searchBluetList = payload;
		},
		setSearchBluetListItem(state, payload){
			state.searchBluetList[payload.index] = payload.item;
		}
	},
	actions: {
		currentBlueData({state, dispatch}, arr){
			let crc = calculateCRC(arr);
			let crcL = crc & 0xFF;       
			let crcH = (crc >> 8) & 0xFF; 
			let dataToSend = new Uint8Array([...arr,`0x${crcL.toString(16)}`,`0x${crcH.toString(16)}`]);
			let buffer = dataToSend.buffer;
			// 写入 BLE 特征值
			uni.writeBLECharacteristicValue({
			    deviceId: state.currentDevice.deviceId,          // 替换为实际设备 ID
			    serviceId: UUID_SERVICE,                         // 替换为实际服务 ID
			    characteristicId: UUID_WRITE,                     // 替换为实际特征 ID
			    value: buffer,
			    success: (res) => {
			        console.log("发送指令成功！", res);
			    },
			    fail: (err) => {
			        console.log("发送指令失败！", err);
			    },
			});
		},
		// BleWrite({state, dispatch},{CMD, data = [], deviceId = ""}) {
		// 	var userInfo = JSON.parse(uni.getStorageSync("userInfo"))
		// 	console.log("deviceId || userInfo.isAdmin::",deviceId , userInfo.isAdmin)
		// 	var defaultArr,bleToken,mobile = userInfo.phone;
		// 	defaultArr = [
		// 		0x1B,
		// 		0x03
		// 	];
		// 	const dataToSend = new Uint8Array([
		// 		...defaultArr,
		// 		...data
		// 	]);
		// 	const buffer = new ArrayBuffer(dataToSend.length + 1);
		// 	const dataView = new DataView(buffer);
		// 	dataToSend.forEach(function callback(element, index, array) {
		// 		dataView.setUint8(index, element);
		// 	});
		// 	const checksum = calculateChecksum(dataToSend);
		// 	dataView.setUint8(dataToSend.length, checksum & 0xff);
		// 	uni.writeBLECharacteristicValue({
		// 		deviceId: deviceId?deviceId:state.currentDevice.deviceId,
		// 		serviceId: UUID_SERVICE,
		// 		characteristicId: UUID_WRITE,
		// 		value: buffer, 
		// 		success: (res) => {
		// 			console.log("发送指令成功！",res)
		// 			setTimeout(() => {
		// 				if(deviceId && state.isAdd){
		// 					state.isAdd = false;
		// 					uni.$emit("addCallback","0000000000000000000000000")
		// 					uni.$off("addCallback");
		// 				}
		// 			}, 1000);
		// 		},
		// 		fail: (err) => {
		// 			uni.$emit("addCallback","0000000000000000000000000")
		// 			uni.$off("addCallback");
		// 		},
		// 	});
		// },
		stopSearchBlue({state, dispatch},callback = null){
			wx.stopBluetoothDevicesDiscovery({
			  success: res => {
				wx.offBluetoothDeviceFound();
				if(callback){
					callback(wx.offBLECharacteristicValueChange)
				}
			  },	
			  fail: err => {
				console.log("stopBluetoothDevicesDiscovery:err",err)
				wx.offBluetoothDeviceFound();
				if(callback){
					callback(wx.offBLECharacteristicValueChange)
				}
			  }
			})
		},
		initBlue({ state, commit, dispatch }, payload=false){
			if(payload){
				uni.openBluetoothAdapter({
					success: () => {	
						uni.getBluetoothAdapterState({
							success: () => {
								let monthFun = () => {
									dispatch("searchBlue", true);
									// uni.getConnectedBluetoothDevices({
									// 	success: res => {
									// 		 if (res.devices.length > 0) {
									// 			state.currentDevice.deviceId = res.devices[0].deviceId;
									// 			uni.setStorageSync("currentDevice",JSON.stringify(state.currentDevice));
									// 			dispatch("currentBlueData");
									// 			console.log("res.devices",res.devices)
									// 		 }else{
									// 			dispatch("searchBlue", true);
									// 		 }
									// 	}
									// })
								};
								let monthFunTime = throttle(monthFun,300); 
								monthFunTime();
							},
							fail: err => {
								uni.showModal({
								  title: '提示',
								  content: '请授权蓝牙',
								  showCancel: false,
								  success: () => {
									uni.openSetting({
									  success(res) {
										  if(res.authSetting["scope.bluetooth"]){
											 dispatch("initBlue", true);
										  }
									  }
									});
								  }
								});
							}
						})
					},
					fail: err => {
						console.log("err",err)
						if(err.errno == 1500102){
							uni.showModal({
							  title: '提示',
							  content: '请打开蓝牙',
							  showCancel: false,
							  success: () => {
								  console.log("蓝牙打开轮询");
								  dispatch("initBlue", true);
							  }
							});
						}else if(err.errno == 103){
							uni.getBluetoothAdapterState({
								success: res => {
									dispatch("searchBlue", true)
								},
								fail: () => {
									uni.showModal({
										title: '提示',
										content: '请授权蓝牙',
										showCancel: false,
										success: () => {
											uni.openSetting({
											  success(res) {
												  if(res.authSetting["scope.bluetooth"]){
													 dispatch("initBlue", true);
												  }
											  }
											});
										}
									});
								}
							})
						}
						
					}
				})
			}else{
				let monthFun = () => {
					dispatch("searchBlue", true)
				};
				let monthFunTime = throttle(monthFun,300); 
				monthFunTime();
			}
		},
		searchBlue({ state, dispatch, commit }, payload = true){
			// uni.navigateTo({
			// 	url: "/pages/search/index"
			// })
			wx.startBluetoothDevicesDiscovery({
				allowDuplicatesKey: true,
				powerLevel: "medium",
				success: () => {
					uni.$emit("onBluetoothDeviceFound",payload);
				},
				fail: err => {
					console.log("searchBlue:err",err)
					let monthFun = () => {
						dispatch("initBlue", true)
					};
					let monthFunTime = throttle(monthFun,300); 
					monthFunTime();
				}
			})
		},
		async onBLEread({state, dispatch, commit}, arr){
			list = list.concat(arr);
			let monthFun = () => {
				console.log("list.length",list.length)
				if(list.length){
					let new_list = list.slice(3, -2);
					let data = splitArrayIntoSubarrays(new_list, 2);
					let result = data.map(item => hexArrayToDecimal(item));
					state.list = result;
					console.log("result",result)
					list = [];
				}
				console.log(":::debounce:::")
			};
			let monthFunTime = debounce(monthFun,500); 
			monthFunTime();
		}
	}
});
export default store;